/**********************************************************************************************
*********   This code constructs calendar-time portfolios for the tests in Table 9    *********
***********************************************************************************************/

/******************************************************************************************************************************
Step 1: Construct a measure of vote alpha at the fund-quarter level
******************************************************************************************************************************/
data quarterly; set temp.fundret_monthly;
  qtr = intnx('quarter', caldt, 0, 'end');
  format qtr date9.;

proc sort data = quarterly nodupkey; by wficn crsp_cl_grp qtr; 
run;

proc sql;
  create table reg as
  select a.wficn, a.crsp_cl_grp, a.qtr, b.permno, b.meetingdate, b.itemonagendaid, b.issForMgmt, b.car12d_m, b.car12d_m_win, 
    b.WinVote, b.margin, b.mgmt_win, b.market_value_pr2, b.market_value_adj, b.voteAgainstMgmt, b.iss_conform
  from quarterly as a, test1 as b
  where a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.meetingdate, a.qtr) <= 12; 
quit;

/***** Calendar-time portfolios;*/
data reg; set reg;
  market_value = abs(market_value_adj);
  if market_value_adj > 0 then i = 1; else if market_value_adj > . then i = -1;

proc sort data = reg nodupkey; by wficn crsp_cl_grp qtr permno meetingdate itemonagendaid; run;

proc means data = reg noprint; by wficn crsp_cl_grp qtr; 
  where car12d_m ne .; 
  var WinVote;
  output out = count2x (drop=_type_ _freq_) n = num_votes;

proc means data = reg noprint; by wficn crsp_cl_grp qtr; 
  var car12d_m_win; weight market_value_adj; 
  output out = win_ret_1x (drop=_type_ _freq_) mean = vote_alpha;

data measure1; merge count2x win_ret_1x; by wficn crsp_cl_grp qtr; 

proc sql;
  create table measure1 as
  select a.*, b.*
  from measure1 as a left join temp.fundinfo as b
  on a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and intck('quarter', b.caldt, a.qtr) = 0; 
quit;

proc sort data = reg; by wficn crsp_cl_grp qtr;

proc means noprint data = reg; by wficn crsp_cl_grp qtr;
  var voteAgainstMgmt iss_conform;
  output out = iss_mgmt_qtr (drop=_type_ _freq_) mean = voteAgainstMgmt_lag iss_conform_lag;
run; 

proc sql;
  create table measure1 as
  select a.*, b.*
  from measure1 as a left join iss_mgmt_qtr as b
  on a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and a.qtr = b.qtr;
quit;

proc sql;
  create table measure1 as
  select a.*, b.flow_style_adj as flow_style_adj_pr12
  from measure1 as a left join temp.flow_qtrly as b
  on a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and intck('quarter', b.qtr, a.qtr) = 0;
quit;

proc sql;
  create table measure1 as
  select a.*, b.mret as mret_pr12, b.mret_style_adj as mret_style_adj_pr12
  from measure1 as a left join temp.fundret_qtr_annual as b
  on a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and intck('quarter', b.qtr, a.qtr) = 0;
quit; 

data measure1b; set measure1;
  if index(crsp_obj_cd2, 'ED') = 1 and num_votes > 10 and mtna >= 5
    and mtna ne . and family_tna ne . and institutional_fund ne . and index_fund2 ne . and mret_style_adj_pr12 ne . and flow_style_adj_pr12 ne . and turnover ne . 
    and expenses2 ne . and frnt_ld2+rear_ld2 ne . and voteagainstmgmt_lag ne . and iss_conform_lag ne . and size_score ne .; 
run;

proc sort data = measure1b; by qtr;

proc rank data = measure1b out  = measure1b groups = 5; by qtr;
  var vote_alpha;
  ranks q_vote_alpha;

data temp.measure_qtr; set measure1b;
  if q_vote_alpha = 4 then informed = 1; else informed = 0;
  if qtr <= '30jun2018'd;
run;




/******************************************************************************************************************************
Step 2: Link the measures to mutual fund holdings and sort stocks into quintiles based on informed ownership
******************************************************************************************************************************/
data s12_holdings; set temp.s12_holdings; * temp.s12_holdings is from 02Holdings.sas;
  rqdate = intnx('quarter', rdate, 0, 'end');
  format rqdate date9.;
  wt = wt_adj;
  keep wficn rqdate rdate permno market_value wt;

proc sort data = s12_holdings; by permno rqdate wficn rdate;

data s12_holdings; set s12_holdings; by permno rqdate wficn;
  if last.wficn;

proc sql;
  create table informed1a as
  select a.informed, a.q_vote_alpha, a.qtr, a.wficn, a.crsp_cl_grp, b.*
  from temp.measure_qtr as a left join s12_holdings as b
  on a.wficn = b.wficn and a.qtr = b.rqdate;
quit; 


data holdings; set temp.holdings;
  rqdate = intnx('quarter', report_dt, 0, 'end');
  format rqdate date9.;
  keep crsp_cl_grp rqdate report_dt permno market_value wt;

proc sort data = holdings; by permno rqdate crsp_cl_grp report_dt;

data holdings; set holdings; by permno rqdate crsp_cl_grp;
  if last.crsp_cl_grp;

data measure_qtrly; set informed1a;
  if rqdate = .;
  drop rqdate rdate permno market_value wt;

proc sql;
  create table informed1b as
  select a.informed, a.q_vote_alpha, a.qtr, a.wficn, a.crsp_cl_grp, b.*
  from measure_qtrly as a left join holdings as b
  on a.crsp_cl_grp = b.crsp_cl_grp and a.qtr = b.rqdate;
quit; 

data informed2; set informed1a informed1b;
  if wt > 0;
  if qtr >= '30jun2004'd;

*** retrieve common stocks;
proc sort data=crsp.stocknames(keep=permco permno ncusip cusip ticker comnam namedt nameenddt st_date end_date shrcd exchcd where=(not missing(ncusip))) 
  out=permno nodupkey; by permno namedt nameenddt;
run;

proc sql;
  create table informed2 as
  select a.*, b.shrcd, b.exchcd
  from informed2 as a left join permno as b
  on a.permno = b.permno and b.namedt <= a.qtr <= b.nameenddt;
quit;

proc sort nodupkey; by permno qtr informed wficn crsp_cl_grp;

proc means data = informed2 noprint; by permno qtr; 
  var wt; where informed = 1 and shrcd in (10, 11, 12) and exchcd in (1,2,3);
  output out = informed2a (drop=_type_ _freq_) sum = wt_informed;

proc means data = informed2 noprint; by permno qtr; 
  var wt; where informed = 0 and shrcd in (10, 11, 12) and exchcd in (1,2,3);
  output out = informed2b (drop=_type_ _freq_) sum = wt_uninformed;
run;

data informed3; merge informed2a informed2b; by permno qtr;
  if wt_informed = . and wt_uninformed ne . then wt_informed = 0;
  if wt_informed ne . and wt_uninformed = . then wt_uninformed = 0;
  frac_informed = wt_informed/(wt_informed+wt_uninformed);
  mfo = wt_informed+wt_uninformed;
run;

proc sort data = informed3; by qtr;

proc rank data = informed3 out = informed3 groups = 5; by qtr;
  var wt_informed wt_uninformed frac_informed mfo; 
  ranks q_wt_informed q_wt_uninformed q_frac_informed q_mfo;

proc means data = informed3 n mean; class q_frac_informed;
  var frac_informed mfo wt_informed;
run;

proc sql;
  create table informed3ret as
  select a.*, b.date, b.ret
  from informed3 as a left join crsp.msf as b
  on a.permno = b.permno and intck('quarter', a.qtr, b.date) in (1); 
quit;

proc sql;
  create table informed3ret as
  select a.*, intck('month', b.meetingdate, a.date) as around_meetings
  from informed3ret as a left join temp.stock_meetings as b
  on a.permno = b.permno and intck('month', b.meetingdate, a.date) in (-1, 0, 1);
quit; * temp.stock_meetings is from 05Meetings_CAR.sas;

proc sql;
  create table informed3ret as
  select a.*, b.dgtw_xret, b.dgtw_vwret
  from informed3ret as a left join temp.dgtw_returns as b
  on a.permno = b.permno and intck('month', a.date, b.date) = 0 and b.dgtw_xret ne .;
quit;

proc sql;
  create table informed3ret as
  select a.*, abs(b.prc)*shrout as mktcap_pr1m
  from informed3ret as a left join crsp.msf as b
  on a.permno = b.permno and intck('month', b.date, a.date) = 1;
quit;

proc sort data = informed3ret nodupkey; by q_frac_informed date permno; run;

**** equal-weighted;
proc means data = informed3ret noprint; by q_frac_informed date;
  var ret dgtw_xret; where mktcap_pr1m ne .;
  output out = informed4 (drop=_type_ _freq_) mean = ret dgtw_xret;
run;

proc sql;
  create table cal_port_stocks1 as
  select a.*, b.hml, b.smb, b.mktrf, b.umd, b.rf, a.ret-b.rf as retx
  from informed4 as a, ff.factors_monthly as b
  where year(a.date) = year(b.dateff) and month(a.date) = month(b.dateff);
quit;

proc sort; by date;

proc means data = cal_port_stocks1 noprint; by date; 
  var dgtw_xret; where q_frac_informed in (0, 4);
  output out = count (drop=_type_ _freq_) n = num;

data cal_port_stocks1; merge cal_port_stocks1 count; by date;
  if num = 2; * make sure both the long (Q5) and short (Q1) portfolios are non-missing;
run;run;

proc sort; by q_frac_informed;

proc reg data = cal_port_stocks1; by q_frac_informed; 
  model retx = mktrf smb hml umd; 
quit; run;

proc sql;
  create table cal_port_stocks1b as
  select a.date, a.mktrf, a.smb, a.hml, a.umd, a.retx-b.retx as diff, a.dgtw_xret-b.dgtw_xret as diff_dgtw
  from cal_port_stocks1 as a, cal_port_stocks1 as b
  where a.date = b.date and a.q_frac_informed = 4 and b.q_frac_informed = 0;
quit;


**** value-weighted;
proc means data = informed3ret noprint; by q_frac_informed date;
  var ret dgtw_xret; weight mktcap_pr1m; where mktcap_pr1m ne .;
  output out = informed4 (drop=_type_ _freq_) mean = ret dgtw_xret;
run;

proc sql;
  create table cal_port_stocks2 as
  select a.*, b.hml, b.smb, b.mktrf, b.umd, b.rf, a.ret-b.rf as retx
  from informed4 as a, ff.factors_monthly as b
  where year(a.date) = year(b.dateff) and month(a.date) = month(b.dateff);
quit;

proc sql;
  create table cal_port_stocks2 as
  select a.*, b.ps_vwf 
  from cal_port_stocks2 as a, ff.liq_ps as b
  where year(a.date) = year(b.date) and month(a.date) = month(b.date);
quit;

proc sort; by date;

proc means data = cal_port_stocks2 noprint; by date; 
  var dgtw_xret; where q_frac_informed in (0, 4);
  output out = count2 (drop=_type_ _freq_) n = num;

data cal_port_stocks2; merge cal_port_stocks2 count2; by date;
  if num = 2; * make sure both the long (Q5) and short (Q1) portfolios are non-missing;
run;run;

proc sort; by q_frac_informed;

proc reg data = cal_port_stocks2; by q_frac_informed; 
  model retx = mktrf smb hml umd; 
quit; run;

proc sql;
  create table cal_port_stocks2b as
  select a.date, a.mktrf, a.smb, a.hml, a.umd, a.retx-b.retx as diff, a.dgtw_xret-b.dgtw_xret as diff_dgtw
  from cal_port_stocks2 as a, cal_port_stocks2 as b
  where a.date = b.date and a.q_frac_informed = 4 and b.q_frac_informed = 0;
quit;

data temp.cal_port_stocks; set cal_port_stocks1 (in=a) cal_port_stocks1b (in=a) cal_port_stocks2 (in=b) cal_port_stocks2b (in=b);
  retx = retx*100;
  diff = diff*100;
  mktrf = mktrf*100;
  smb = smb*100; 
  hml = hml*100; 
  umd = umd*100;
  diff_dgtw = diff_dgtw*100;
  dgtw_xret = dgtw_xret*100;
  if a then ew = 1; 
  if b then vw = 1;
  con = 1;

proc reg data = temp.cal_port_stocks; 
  where ew = 1;
  model diff = mktrf smb hml umd; 
quit; run;

proc reg data = temp.cal_port_stocks; 
  where vw = 1;
  model diff_dgtw = con; 
quit; run;


proc export data= temp.cal_port_stocks 
            outfile= "D:\Dropbox\InformedVoting\cal_port_stocks.dta" 
            dbms=stata replace;
run;







*****************************************************************************************************************************************
****************** Splits the monthly returns for each stock into returns in a three-month period around shareholder   ****************** 
****************** meetings (�meeting months�), i.e., from one month before the month of a shareholder meeting to one  ****************** 
****************** month after, and returns outside of the three-month period (�non-meeting months�);                  ******************
*****************************************************************************************************************************************
 
**** Meeting months: equal-weighted;
proc means data = informed3ret noprint; by q_frac_informed date;
  var ret dgtw_xret; where mktcap_pr1m ne . and around_meetings in (-1, 0, 1);
  output out = informed4 (drop=_type_ _freq_) mean = ret dgtw_xret;
run;

proc sql;
  create table cal_port_stocks1 as
  select a.*, b.hml, b.smb, b.mktrf, b.umd, b.rf, a.ret-b.rf as retx
  from informed4 as a, ff.factors_monthly as b
  where year(a.date) = year(b.dateff) and month(a.date) = month(b.dateff);
quit;

proc sort; by date;

proc means data = cal_port_stocks1 noprint; by date; 
  var dgtw_xret; where q_frac_informed in (0, 4);
  output out = count (drop=_type_ _freq_) n = num;

data cal_port_stocks1; merge cal_port_stocks1 count; by date;
  if num = 2; * make sure both the long (Q5) and short (Q1) portfolios are non-missing;
run;run;

proc sql;
  create table cal_port_stocks1b as
  select a.date, a.mktrf, a.smb, a.hml, a.umd, a.retx-b.retx as diff, a.dgtw_xret-b.dgtw_xret as diff_dgtw
  from cal_port_stocks1 as a, cal_port_stocks1 as b
  where a.date = b.date and a.q_frac_informed = 4 and b.q_frac_informed = 0;
quit;


**** Meeting months: value-weighted;
proc means data = informed3ret noprint; by q_frac_informed date;
  var ret dgtw_xret; weight mktcap_pr1m; where mktcap_pr1m ne . and around_meetings in (-1, 0, 1);
  output out = informed4 (drop=_type_ _freq_) mean = ret dgtw_xret;
run;

proc sql;
  create table cal_port_stocks2 as
  select a.*, b.hml, b.smb, b.mktrf, b.umd, b.rf, a.ret-b.rf as retx
  from informed4 as a, ff.factors_monthly as b
  where year(a.date) = year(b.dateff) and month(a.date) = month(b.dateff);
quit;

proc sort; by date;

proc means data = cal_port_stocks2 noprint; by date; 
  var dgtw_xret; where q_frac_informed in (0, 4);
  output out = count2 (drop=_type_ _freq_) n = num;

data cal_port_stocks2; merge cal_port_stocks2 count2; by date;
  if num = 2; * make sure both the long (Q5) and short (Q1) portfolios are non-missing;
run;run;


*** alpha on the long and Short legs separately:  Equal weighted;
proc sort data = cal_port_stocks1; by q_frac_informed;

proc reg data = cal_port_stocks1; by q_frac_informed; 
  where q_frac_informed in (0, 4); *;
  model retx = mktrf smb hml umd; 
quit; run;

proc means data = cal_port_stocks1 n mean t probt; class q_frac_informed; where q_frac_informed in (0, 4);
  var dgtw_xret;
run;

proc ttest data = cal_port_stocks1; class q_frac_informed; where q_frac_informed in (0, 4);
  var dgtw_xret;
run;

*** alpha on the long and Short legs separately:  Value weighted;
proc sort data = cal_port_stocks2; by q_frac_informed;

proc reg data = cal_port_stocks2; by q_frac_informed; 
  where q_frac_informed in (0, 4); 
  model retx = mktrf smb hml umd; 
quit; run;

proc means data = cal_port_stocks2 n mean t probt; class q_frac_informed; where q_frac_informed in (0, 4);
  var dgtw_xret;
run;

proc ttest data = cal_port_stocks2; class q_frac_informed; where q_frac_informed in (0, 4);
  var dgtw_xret;
run;

proc sql;
  create table cal_port_stocks2b as
  select a.date, a.mktrf, a.smb, a.hml, a.umd, a.retx-b.retx as diff, a.dgtw_xret-b.dgtw_xret as diff_dgtw
  from cal_port_stocks2 as a, cal_port_stocks2 as b
  where a.date = b.date and a.q_frac_informed = 4 and b.q_frac_informed = 0;
quit;

data cal_port_meetingmonths; set cal_port_stocks1 (in=a) cal_port_stocks1b (in=a) cal_port_stocks2 (in=b) cal_port_stocks2b (in=b);
  retx = retx*100;
  diff = diff*100;
  mktrf = mktrf*100;
  smb = smb*100; 
  hml = hml*100; 
  umd = umd*100;
  diff_dgtw = diff_dgtw*100;
  dgtw_xret = dgtw_xret*100;
  if a then ew = 1; 
  if b then vw = 1;
  con = 1;

proc reg data = cal_port_meetingmonths; 
  where ew = 1;
  model diff = mktrf smb hml umd;
quit; run;

proc reg data = cal_port_meetingmonths; 
  where vw = 1;
  model diff = mktrf smb hml umd;
quit; run;

proc reg data = cal_port_meetingmonths; 
  where ew = 1;
  model diff_dgtw = con; 
quit; run;

proc reg data = cal_port_meetingmonths; 
  where vw = 1;
  model diff_dgtw = con; 
quit; run;


proc export data= cal_port_meetingmonths 
            outfile= "D:\Dropbox\InformedVoting\cal_port_meetingmonths.dta" 
            dbms=stata replace;
run;




**** Non-meeting months: equal-weighted;
proc means data = informed3ret noprint; by q_frac_informed date;
  var ret dgtw_xret; where mktcap_pr1m ne . and around_meetings not in (-1, 0, 1);
  output out = informed4 (drop=_type_ _freq_) mean = ret dgtw_xret;
run;

proc sql;
  create table cal_port_stocks1 as
  select a.*, b.hml, b.smb, b.mktrf, b.umd, b.rf, a.ret-b.rf as retx
  from informed4 as a, ff.factors_monthly as b
  where year(a.date) = year(b.dateff) and month(a.date) = month(b.dateff);
quit;

proc sort; by date;

proc means data = cal_port_stocks1 noprint; by date; 
  var dgtw_xret; where q_frac_informed in (0, 4);
  output out = count (drop=_type_ _freq_) n = num;

data cal_port_stocks1; merge cal_port_stocks1 count; by date;
  if num = 2; * make sure both the long (Q5) and short (Q1) portfolios are non-missing;
run;run;

proc sql;
  create table cal_port_stocks1b as
  select a.date, a.mktrf, a.smb, a.hml, a.umd, a.retx-b.retx as diff, a.dgtw_xret-b.dgtw_xret as diff_dgtw
  from cal_port_stocks1 as a, cal_port_stocks1 as b
  where a.date = b.date and a.q_frac_informed = 4 and b.q_frac_informed = 0;
quit;


**** Non-meeting months: value-weighted;
proc means data = informed3ret noprint; by q_frac_informed date;
  var ret dgtw_xret; weight mktcap_pr1m; where mktcap_pr1m ne . and around_meetings not in (-1, 0, 1);
  output out = informed4 (drop=_type_ _freq_) mean = ret dgtw_xret;
run;

proc sql;
  create table cal_port_stocks2 as
  select a.*, b.hml, b.smb, b.mktrf, b.umd, b.rf, a.ret-b.rf as retx
  from informed4 as a, ff.factors_monthly as b
  where year(a.date) = year(b.dateff) and month(a.date) = month(b.dateff);
quit;

proc sort; by date;

proc means data = cal_port_stocks2 noprint; by date; 
  var dgtw_xret; where q_frac_informed in (0, 4);
  output out = count2 (drop=_type_ _freq_) n = num;

data cal_port_stocks2; merge cal_port_stocks2 count2; by date;
  if num = 2; * make sure both the long (Q5) and short (Q1) portfolios are non-missing;
run;run;

*** alpha on the long and Short legs separately:  Equal weighted;
proc sort data = cal_port_stocks1; by q_frac_informed;

proc reg data = cal_port_stocks1; by q_frac_informed; 
  where q_frac_informed in (0, 4); *;
  model retx = mktrf smb hml umd; 
quit; run;

proc means data = cal_port_stocks1 n mean t probt; class q_frac_informed; where q_frac_informed in (0, 4);
  var dgtw_xret;
run;

proc ttest data = cal_port_stocks1; class q_frac_informed; where q_frac_informed in (0, 4);
  var dgtw_xret;
run;

*** alpha on the long and Short legs separately:  Value weighted;
proc sort data = cal_port_stocks2; by q_frac_informed;

proc reg data = cal_port_stocks2; by q_frac_informed; 
  where q_frac_informed in (0, 4); 
  model retx = mktrf smb hml umd; 
quit; run;

proc means data = cal_port_stocks2 n mean t probt; class q_frac_informed; where q_frac_informed in (0, 4);
  var dgtw_xret;
run;

proc ttest data = cal_port_stocks2; class q_frac_informed; where q_frac_informed in (0, 4);
  var dgtw_xret;
run;

proc sql;
  create table cal_port_stocks2b as
  select a.date, a.mktrf, a.smb, a.hml, a.umd, a.retx-b.retx as diff, a.dgtw_xret-b.dgtw_xret as diff_dgtw
  from cal_port_stocks2 as a, cal_port_stocks2 as b
  where a.date = b.date and a.q_frac_informed = 4 and b.q_frac_informed = 0;
quit;


data cal_port_nonmeetingmonths; set cal_port_stocks1 (in=a) cal_port_stocks1b (in=a) cal_port_stocks2 (in=b) cal_port_stocks2b (in=b);
  retx = retx*100;
  diff = diff*100;
  mktrf = mktrf*100;
  smb = smb*100; 
  hml = hml*100; 
  umd = umd*100;
  rmw = rmw*100;
  cma = cma*100;
  diff_dgtw = diff_dgtw*100;
  dgtw_xret = dgtw_xret*100;
  if a then ew = 1; 
  if b then vw = 1;
  con = 1;

proc reg data = cal_port_nonmeetingmonths; 
  where ew = 1;
  model diff = mktrf smb hml umd;
quit; run;

proc reg data = cal_port_nonmeetingmonths; 
  where vw = 1;
  model diff = mktrf smb hml umd;
quit; run;

proc reg data = cal_port_nonmeetingmonths; 
  where ew = 1;
  model diff_dgtw = con; 
quit; run;

proc reg data = cal_port_nonmeetingmonths; 
  where vw = 1;
  model diff_dgtw = con; 
quit; run;



proc export data= cal_port_nonmeetingmonths 
            outfile= "D:\Dropbox\InformedVoting\cal_port_nonmeetingmonths.dta" 
            dbms=stata replace;
run; 
